package main

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"sync"
)

func main() {
	http.HandleFunc("/test", handler)
	if err := http.ListenAndServeTLS(":8080", "server.crt","server.key",nil); err != nil {
		log.Fatal(err)
	}
}

func handler(w http.ResponseWriter, r *http.Request) {
	bytes, err := ioutil.ReadAll(r.Body)
	if err != nil {
		fmt.Println(err)
		return
	}
	var p Param
	err = json.Unmarshal(bytes, &p)
	if err != nil {
		fmt.Printf("Unmarshal fail:%v", err)
		return
	}
	fmt.Println(p)
	res := c.Check(p.Vale)
	c.Store(p.Vale)
	marshal, err := json.Marshal(res)
	if err != nil {
		w.Write([]byte(err.Error()))
	}
	w.Write(marshal)
}

type (
	Count struct {
		cache map[string][][]int
		n     int
		mu    sync.Mutex
	}
	Param struct {
		Vale []string `json:"data"`
	}
)

var (
	c = Count{
		cache: make(map[string][][]int),
		n:     1,
		mu:    sync.Mutex{},
	}
)

func (this *Count) Check(p []string) []bool {
	this.mu.Lock()
	defer this.mu.Unlock()
	r := make([]bool, 0, len(p))
	for _, item := range p {
		if _, ok := this.cache[item]; ok {
			r = append(r, true)
		} else {
			r = append(r, false)
		}
	}
	return r
}

func (this *Count) Store(p []string) {
	this.mu.Lock()
	defer this.mu.Unlock()
	for idx, item := range p {
		if v, ok := this.cache[item]; ok {
			this.cache[item] = append(v, []int{this.n, idx})
		} else {
			this.cache[item] = [][]int{{1, idx}}
		}
	}
	this.n++
}
